package tv.accedo.achi.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import tv.accedo.achi.dao.AppDao;
import tv.accedo.achi.dao.BadgeDao;
import tv.accedo.achi.dao.UserDao;
import tv.accedo.achi.model.Achi;
import tv.accedo.achi.model.Badge;
import tv.accedo.achi.model.User;

/**
 * The business logic service of badge relevant functionality.
 * @author Bo Liang
 *
 */
@Component
public class BadgeService {

	private User user; //injection
	private UserDao userDao; //injection
	private Badge badge; //injection
	private BadgeDao badgeDao; //injection
	private Achi achi; //injection
	private AppDao appDao; //injection
	
	/**
	 * Add badge to user object.
	 * @param username 	user name
	 * @param badge_sn	badge serial number
	 */
	public void addBadgeToUser(String username, String badge_sn) {
		badgeDao.addBadgeToUser(username, badge_sn); 
	}
	
	/**
	 * Get all badges in two categories : unlocked and locked.
	 * <p>unlocked badges have a state value 'true',
	 * and locked badges have a state value 'false'.<br>
	 * in front-end, the true state will make the badge colored,
	 * and the false state will make the badge dim.
	 * @param username	user name
	 * @return			JSON badges
	 */
	public String getJsonBadgesByUsername(String username) {
		List<Badge> badgeList = new ArrayList<Badge>();
		Map<Integer, String> unlockedBadgeIdMap = new HashMap<Integer, String>();
		String state = "none";
		user = userDao.getUserByUsername(username); 
		
		// get all badges to the badge List
		badgeList = badgeDao.getAllBadges(); 
		// get user unlocked badges id to the unlocked badge id list
		unlockedBadgeIdMap = badgeDao.getUnlockedBadgesIdByUserId(user.getId());
		
		String jsonBadges = "]}";
		for (Iterator<Badge> iter = badgeList.iterator(); iter.hasNext(); ) {
			badge = iter.next();
			
			if (unlockedBadgeIdMap.containsKey(badge.getId())) {
				state = unlockedBadgeIdMap.get(badge.getId());	// true means user already unlocked this badge and will colored displayed in front-end
			} else {
				state = "none";	// false means user did not unlock this badge and will dim displayed in front-end
			}
			jsonBadges = "{badge_sn:'" + badge.getBadge_sn() + "', badge_name:'" + badge.getBadge_name() + "', state:'" + state + "'},"
				+ jsonBadges;
		}
		jsonBadges = "{badges:[" + jsonBadges;
		
		try {
			Thread.sleep(1800);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jsonBadges; 
	}
	
	public String getJsonBadgesByUsernameForFriendShow(String username) {
		List<Badge> badgeList = new ArrayList<Badge>();
		Map<Integer, String> unlockedBadgeIdMap = new HashMap<Integer, String>();
		String state = "none";
		user = userDao.getUserByUsername(username); 
		
		// get all badges to the badge List
		badgeList = badgeDao.getAllBadges(); 
		// get user unlocked badges id to the unlocked badge id list
		unlockedBadgeIdMap = badgeDao.getUnlockedBadgesIdByUserId(user.getId());
		
		String jsonBadges = "]}";
		String jsonBadgesFinished = "";
		String jsonBadgesPlaying = "";
		String jsonBadgesNone = "";
		for (Iterator<Badge> iter = badgeList.iterator(); iter.hasNext(); ) {
			badge = iter.next();
			
			if (unlockedBadgeIdMap.containsKey(badge.getId())) {
				state = unlockedBadgeIdMap.get(badge.getId());	// true means user already unlocked this badge and will colored displayed in front-end
				if (state == "playing") {
					jsonBadgesPlaying = "{badge_sn:'" + badge.getBadge_sn() + "', badge_name:'" + badge.getBadge_name() + "', state:'" + state + "'},"
					+ jsonBadgesPlaying;
				} else if (state == "finished") {
					jsonBadgesFinished = "{badge_sn:'" + badge.getBadge_sn() + "', badge_name:'" + badge.getBadge_name() + "', state:'" + state + "'},"
					+ jsonBadgesFinished;
				}
			} else {
				state = "none";	// false means user did not unlock this badge and will dim displayed in front-end
				jsonBadgesNone = "{badge_sn:'" + badge.getBadge_sn() + "', badge_name:'" + badge.getBadge_name() + "', state:'" + state + "'},"
				+ jsonBadgesNone;
			}
			
		}
		jsonBadges = "{badges:[" + jsonBadgesFinished + jsonBadgesPlaying + jsonBadgesNone + jsonBadges;
		
		try {
			Thread.sleep(1800);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jsonBadges; 
	}
	
	/**
	 * Return the achievements list with whether user unlocked or not, that belongs to the badge.
	 * <p>badge includes batch of achievements.<br>
	 * This function return the name of achievement and the application it belongs to, and state of the user whether unlocked it or not.
	 * @param badge_sn	badge serial number
	 * @param username	user name
	 * @return			JSON format badgeAchis
	 */
	public String getJsonAchisByBadgesnAndUsername(String badge_sn, String username) {
		List<String> achiSnList = new ArrayList<String>(); 
		Set<Achi> achiSet = new HashSet<Achi>(); 
		String jsonAchis = "]}";
		
		// get all achievements belongs to the badge
		achiSet = badgeDao.getAchisByBadgesn(badge_sn); 
		user = userDao.getUserByUsername(username); 
		
		// get user's unlocked achievements sn into achievement sn list
		for (Iterator<Achi> iterUser = user.getAchis().iterator(); iterUser.hasNext(); ) {
			achiSnList.add(iterUser.next().getAchi_sn()); 
		}
		
		for (Iterator<Achi> iter = achiSet.iterator(); iter.hasNext(); ) {
			achi = iter.next(); 
			String app_sn = achi.getApp_sn(); 
			String app_name = appDao.getAppByAppsn(app_sn).getApp_name();
			boolean state = false; 
			// if this achievement belongs the user's unlocked achievement list, assign the start in true
			if (achiSnList.contains(achi.getAchi_sn())) {
				state = true;
			}
			
			jsonAchis = "{app_sn:'" + app_sn 
					+ "', app_name:'" + app_name 
					+ "', achi_sn:'" + achi.getAchi_sn()
					+ "', achi_name:'" + achi.getAchi_name() 
					+ "', state:'" + state + "'},"
				+ jsonAchis;
		}
		jsonAchis = "{badgeAchis:[" + jsonAchis;
		
		return jsonAchis; 
	}

	public BadgeDao getBadgeDao() {
		return badgeDao;
	}

	@Resource
	public void setBadgeDao(BadgeDao badgeDao) {
		this.badgeDao = badgeDao;
	}

	public User getUser() {
		return user;
	}

	@Resource
	public void setUser(User user) {
		this.user = user;
	}

	public Badge getBadge() {
		return badge;
	}

	@Resource
	public void setBadge(Badge badge) {
		this.badge = badge;
	}

	public UserDao getUserDao() {
		return userDao;
	}

	@Resource
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public Achi getAchi() {
		return achi;
	}

	@Resource
	public void setAchi(Achi achi) {
		this.achi = achi;
	}

	public AppDao getAppDao() {
		return appDao;
	}

	@Resource
	public void setAppDao(AppDao appDao) {
		this.appDao = appDao;
	}
	
}
